﻿using System.Collections;
using System.Data.Common;

namespace SimpleORM
{
    public enum eDbExecuteType
    {
        Reader,
        NonQuery,
        Scalar
    }
    public interface IDbCCommand : IDCommand
    {
        #region Methods

        object ExecuteReader();
        object ExecuteScalar();
        int ExecuteNonQuery();

        #endregion
    }
    public abstract class DCommand : CDObject, IDCommand
    {
        #region Properties

        public virtual string CommandText { get; set; }
        public virtual int CommandTimeout { get; set; }
        public virtual object Argument { get; set; }
        public virtual IList Parameters { get; protected set; }

        #endregion

        #region Ctor

        public DCommand()
        {
        }

        #endregion

        #region Methods

        #region Methods - Execute

        public virtual object Execute()
        {
            return null;
        }

        #endregion

        #region Methods - Override

        public override string ToString()
        {
            return CommandText;
        }

        #endregion

        #endregion
    }
    public class DbCCommand : DCommand, IDbCCommand
    {
        #region Properties

        public DbCommand Instance { get; set; }

        public override string CommandText
        {
            get { return Instance.CommandText; }
            set { Instance.CommandText = value; }
        }

        public override IList Parameters
        {
            get { return Instance.Parameters; }
            protected set { base.Parameters = Instance.Parameters; }
        }

        public override int CommandTimeout
        {
            get { return Instance.CommandTimeout; }
            set { Instance.CommandTimeout = value; }
        }

        #endregion

        #region Ctor

        public DbCCommand()
        {
        }

        public DbCCommand(DbCommand cmd)
            : this()
        {
            Instance = cmd;
        }

        #endregion

        #region Methods

        #region Methods - Execute

        public override object Execute()
        {
            eDbExecuteType type = eDbExecuteType.Reader;
            if (Argument is eDbExecuteType)
                type = (eDbExecuteType)Argument;

            switch (type)
            {
                case eDbExecuteType.Reader:
                    return ExecuteReader();

                case eDbExecuteType.NonQuery:
                    return ExecuteNonQuery();

                case eDbExecuteType.Scalar:
                    return ExecuteScalar();

                default:
                    return ExecuteReader();
            }
        }

        public virtual object ExecuteReader()
        {
            if (Instance.Connection.State == System.Data.ConnectionState.Closed)
                Instance.Connection.Open();
            return Instance.ExecuteReader();
        }

        public virtual object ExecuteScalar()
        {
            if (Instance.Connection.State == System.Data.ConnectionState.Closed)
                Instance.Connection.Open();
            return Instance.ExecuteScalar();
        }

        public virtual int ExecuteNonQuery()
        {
            if (Instance.Connection.State == System.Data.ConnectionState.Closed)
                Instance.Connection.Open();
            return Instance.ExecuteNonQuery();
        }

        #endregion

        #region Methods - Override

        public override void Dispose()
        {
            base.Dispose();

            Instance = null;
        }

        #endregion

        #endregion
    }
}
